/// 旋转点
///
/// x, y: 旋转前的点
/// anchor_x, anchor_y: 旋转中心
/// rotate: 旋转角度(角度制)
/// 返回值: 旋转后的点
pub fn rotate_point(x: f32, y: f32, anchor_x: f32, anchor_y: f32, rotate: f32) -> (f32, f32) {
    let dx = x - anchor_x;
    let dy = y - anchor_y;
    let rad = (-rotate).to_radians(); // 将角度制转换为弧度制
    let cos_r = rad.cos();
    let sin_r = rad.sin();
    let new_x = dx * cos_r - dy * sin_r;
    let new_y = dx * sin_r + dy * cos_r;
    (new_x + anchor_x, new_y + anchor_y)
}

pub fn flip_point(x: f32, y:f32, anchor_x: f32, anchor_y: f32, flip_x:bool, flip_y:bool) -> (f32, f32) {
    let dx = x - anchor_x;
    let dy = y - anchor_y;
    let new_x = if flip_x { -dx } else { dx };
    let new_y = if flip_y { -dy } else { dy };
    (new_x + anchor_x, new_y + anchor_y)
}

#[allow(dead_code)]
pub fn scale_point(x: f32, y:f32, anchor_x: f32, anchor_y: f32, scale:(f32, f32)) -> (f32, f32) {
    let dx = x - anchor_x;
    let dy = y - anchor_y;
    let new_x = dx * scale.0;
    let new_y = dy * scale.1;
    (new_x + anchor_x, new_y + anchor_y)
}

/// 将地图坐标转换为世界坐标
/// x, y: 地图坐标
/// 返回值: 世界坐标
/// 说明: 地图坐标原点在左上角，世界坐标原点在左下角
///     地图坐标的 y 轴是向下的，世界坐标的 y 轴是向上的
pub fn point_posconv(map: Option<&tiled::Map>, x: f32, y: f32) -> (f32, f32) {
    let Some(map) = map else { return (x, y); };
    match map.orientation {
        tiled::Orientation::Orthogonal => {
            // 对于正交地图，假设左下角为原点，y 轴向上
            let new_y = (map.height * map.tile_height) as f32 - y;
            (x, new_y)
        },
        tiled::Orientation::Isometric => {
            // 对于等距地图，将像素坐标转换为左下角为原点的直角坐标系
            let tile_width = map.tile_width as f32;
            let tile_height = map.tile_height as f32;
            let map_width: f32 = map.width as f32;
            let map_height = map.height as f32;
            let half_tile_width = tile_width / 2.0;
            let half_tile_height = tile_height / 2.0;

            // 计算索引
            let pos_idx_x = x / tile_height;
            let pos_idx_y = y / tile_height;

            // 根据地图大小进行调整计算新的坐标
            let new_x = half_tile_width * (map_height + pos_idx_x - pos_idx_y);
            let new_y = half_tile_height * (map_width + map_height - pos_idx_x - pos_idx_y);
            // println!("conv:({},{}) -> ({}, {})", x, y, new_x, new_y);
            (new_x, new_y)
        },
        _ => (x, y),//其他情况暂时不处理
    }
}

pub fn conv_tileset_localpos(map: &tiled::Map, real_size: &(f32, f32), normal_size:&(f32, f32), point:&(f32, f32), tile_obj:&tiled::Object) -> (f32, f32) {
    let anchor_point = point_posconv(Some(map), tile_obj.x, tile_obj.y);
    match map.orientation {
        tiled::Orientation::Isometric => {
            //对于等距地图，锚点是底部中心，所以所以需要转换
            let tile_width = real_size.0;
            let tile_height: f32 = real_size.1;
            let half_tile_width = tile_width / 2.0;

            let scale_x = real_size.0 / normal_size.0;
            let scale_y = real_size.1 / normal_size.1;

            let scaled_point = (point.0 * scale_x, point.1 * scale_y);

            let result = (anchor_point.0 + scaled_point.0 - half_tile_width, anchor_point.1 + tile_height - scaled_point.1);
            let result = rotate_point(result.0, result.1, anchor_point.0, anchor_point.1, tile_obj.rotation);
            result
        },
        tiled::Orientation::Orthogonal => {
            //因为tileset的锚点在左上角，x不变, y需要用tile_height减去
            let scale_x = real_size.0 / normal_size.0;
            let scale_y = real_size.1 / normal_size.1;
            let tile_height = real_size.1 as f32;
            let point = (point.0 * scale_x, point.1 * scale_y);
            let result = (anchor_point.0 + point.0, anchor_point.1 + tile_height - point.1);
            let result = rotate_point(result.0, result.1, anchor_point.0, anchor_point.1, tile_obj.rotation);
            result
        },
        _ => {
            let scale_x = real_size.0 / normal_size.0;
            let scale_y = real_size.1 / normal_size.1;
            let point = (point.0 * scale_x, point.1 * scale_y);
            (point.0, point.1)
        },//其他情况暂时不处理
    }
}

